home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / OTHERCST / JPSRC_FO / JCMAIN.C < prev    next >
Text File  |  1991-10-13  |  7KB  |  273 lines

  1. /*
  2.  * jcmain.c
  3.  *
  4.  * Copyright (C) 1991, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains a trivial test user interface for the JPEG compressor.
  9.  * It should work on any system with Unix- or MS-DOS-style command lines.
  10.  *
  11.  * Two different command line styles are permitted, depending on the
  12.  * compile-time switch TWO_FILE_COMMANDLINE:
  13.  *    cjpeg [options]  inputfile outputfile
  14.  *    cjpeg [options]  [inputfile]
  15.  * In the second style, output is always to standard output, which you'd
  16.  * normally redirect to a file or pipe to some other program.  Input is
  17.  * either from a named file or from standard input (typically redirected).
  18.  * The second style is convenient on Unix but is unhelpful on systems that
  19.  * don't support pipes.  Also, you MUST use the first style if your system
  20.  * doesn't do binary I/O to stdin/stdout.
  21.  */
  22.  
  23. #include "jinclude.h"
  24. #ifdef __STDC__
  25. #include <stdlib.h>        /* to declare exit() */
  26. #endif
  27.  
  28. #ifdef THINK_C
  29. #include <console.h>        /* command-line reader for Macintosh */
  30. #endif
  31.  
  32. #ifdef DONT_USE_B_MODE        /* define mode parameters for fopen() */
  33. #define READ_BINARY    "r"
  34. #define WRITE_BINARY    "w"
  35. #else
  36. #define READ_BINARY    "rb"
  37. #define WRITE_BINARY    "wb"
  38. #endif
  39.  
  40.  
  41. /*
  42.  * If your system has getopt(3), you can use your library version by
  43.  * defining HAVE_GETOPT.  By default, we use the PD 'egetopt'.
  44.  */
  45.  
  46. #ifdef HAVE_GETOPT
  47. extern int getopt PP((int argc, char **argv, char *optstring));
  48. extern char * optarg;
  49. extern int optind;
  50. #else
  51. #include "egetopt.c"
  52. #define getopt(argc,argv,opt)    egetopt(argc,argv,opt)
  53. #endif
  54.  
  55.  
  56. /*
  57.  * This routine determines what format the input file is,
  58.  * and selects the appropriate input-reading module.
  59.  *
  60.  * To determine which family of input formats the file belongs to,
  61.  * we look only at the first byte of the file, since C does not
  62.  * guarantee that more than one character can be pushed back with ungetc.
  63.  * This is sufficient for the currently envisioned set of input formats.
  64.  *
  65.  * If you need to look at more than one character to select an input module,
  66.  * you can either
  67.  *     1) assume you can fseek() the input file (may fail for piped input);
  68.  *     2) assume you can push back more than one character (works in
  69.  *        some C implementations, but unportable);
  70.  * or  3) don't put back the data, and modify the various input_init
  71.  *        methods to assume they start reading after the start of file.
  72.  */
  73.  
  74. LOCAL void
  75. select_file_type (compress_info_ptr cinfo)
  76. {
  77.   int c;
  78.  
  79.   if ((c = getc(cinfo->input_file)) == EOF)
  80.     ERREXIT(cinfo->emethods, "Empty input file");
  81.  
  82.   switch (c) {
  83. #ifdef GIF_SUPPORTED
  84.   case 'G':
  85.     jselrgif(cinfo);
  86.     break;
  87. #endif
  88. #ifdef PPM_SUPPORTED
  89.   case 'P':
  90.     jselrppm(cinfo);
  91.     break;
  92. #endif
  93.   default:
  94.     ERREXIT(cinfo->emethods, "Unsupported input file format");
  95.     break;
  96.   }
  97.  
  98.   if (ungetc(c, cinfo->input_file) == EOF)
  99.     ERREXIT(cinfo->emethods, "ungetc failed");
  100. }
  101.  
  102.  
  103. /*
  104.  * This routine gets control after the input file header has been read.
  105.  * It must determine what output JPEG file format is to be written,
  106.  * and make any other compression parameter changes that are desirable.
  107.  */
  108.  
  109. METHODDEF void
  110. c_ui_method_selection (compress_info_ptr cinfo)
  111. {
  112.   /* If the input is gray scale, generate a monochrome JPEG file. */
  113.   if (cinfo->in_color_space == CS_GRAYSCALE)
  114.     j_monochrome_default(cinfo);
  115.   /* For now, always select JFIF output format. */
  116. #ifdef JFIF_SUPPORTED
  117.   jselwjfif(cinfo);
  118. #else
  119.   You shoulda defined JFIF_SUPPORTED.   /* deliberate syntax error */
  120. #endif
  121. }
  122.  
  123.  
  124. LOCAL void
  125. usage (char * progname)
  126. /* complain about bad command line */
  127. {
  128.   fprintf(stderr, "usage: %s ", progname);
  129.   fprintf(stderr, "[-I] [-Q quality 0..100] [-a] [-o] [-d]");
  130. #ifdef TWO_FILE_COMMANDLINE
  131.   fprintf(stderr, " inputfile outputfile\n");
  132. #else
  133.   fprintf(stderr, " [inputfile]\n");
  134. #endif
  135.   exit(2);
  136. }
  137.  
  138.  
  139. /*
  140.  * The main program.
  141.  */
  142.  
  143. GLOBAL void
  144. main (int argc, char **argv)
  145. {
  146.   struct compress_info_struct cinfo;
  147.   struct compress_methods_struct c_methods;
  148.   struct external_methods_struct e_methods;
  149.   int c;
  150.  
  151.   /* On Mac, fetch a command line. */
  152. #ifdef THINK_C
  153.   argc = ccommand(&argv);
  154. #endif
  155.  
  156.   /* Initialize the system-dependent method pointers. */
  157.   cinfo.methods = &c_methods;
  158.   cinfo.emethods = &e_methods;
  159.   jselerror(&e_methods);    /* error/trace message routines */
  160.   jselvirtmem(&e_methods);    /* memory allocation routines */
  161.   c_methods.c_ui_method_selection = c_ui_method_selection;
  162.  
  163.   /* Set up default input and output file references. */
  164.   /* (These may be overridden below.) */
  165.   cinfo.input_file = stdin;
  166.   cinfo.output_file = stdout;
  167.  
  168.   /* Set up default parameters. */
  169.   e_methods.trace_level = 0;
  170.   j_default_compression(&cinfo, 75); /* default quality level */
  171.  
  172.   /* Scan parameters */
  173.   
  174.   while ((c = getopt(argc, argv, "IQ:aod")) != EOF)
  175.     switch (c) {
  176.     case 'I':            /* Create noninterleaved file. */
  177. #ifdef MULTISCAN_FILES_SUPPORTED
  178.       cinfo.interleave = FALSE;
  179. #else
  180.       fprintf(stderr, "%s: sorry, multiple-scan support was not compiled\n",
  181.           argv[0]);
  182.       exit(2);
  183. #endif
  184.       break;
  185.     case 'Q':            /* Quality factor. */
  186.       { int val;
  187.     if (optarg == NULL)
  188.       usage(argv[0]);
  189.     if (sscanf(optarg, "%d", &val) != 1)
  190.       usage(argv[0]);
  191.     /* Note: for now, we leave force_baseline FALSE.
  192.      * In a production user interface, probably should make it TRUE
  193.      * unless overridden by a separate switch.
  194.      */
  195.     j_set_quality(&cinfo, val, FALSE);
  196.       }
  197.       break;
  198.     case 'a':            /* Use arithmetic coding. */
  199. #ifdef ARITH_CODING_SUPPORTED
  200.       cinfo.arith_code = TRUE;
  201. #else
  202.       fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
  203.           argv[0]);
  204.       exit(2);
  205. #endif
  206.       break;
  207.     case 'o':            /* Enable entropy parm optimization. */
  208. #ifdef ENTROPY_OPT_SUPPORTED
  209.       cinfo.optimize_coding = TRUE;
  210. #else
  211.       fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
  212.           argv[0]);
  213.       exit(2);
  214. #endif
  215.       break;
  216.     case 'd':            /* Debugging. */
  217.       e_methods.trace_level++;
  218.       break;
  219.     case '?':
  220.     default:
  221.       usage(argv[0]);
  222.       break;
  223.     }
  224.  
  225.   /* Select the input and output files */
  226.  
  227. #ifdef TWO_FILE_COMMANDLINE
  228.  
  229.   if (optind != argc-2) {
  230.     fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
  231.     usage(argv[0]);
  232.   }
  233.   if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  234.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  235.     exit(2);
  236.   }
  237.   if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
  238.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
  239.     exit(2);
  240.   }
  241.  
  242. #else /* not TWO_FILE_COMMANDLINE -- use Unix style */
  243.  
  244.   if (optind < argc-1) {
  245.     fprintf(stderr, "%s: only one input file\n", argv[0]);
  246.     usage(argv[0]);
  247.   }
  248.   if (optind < argc) {
  249.     if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  250.       fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  251.       exit(2);
  252.     }
  253.   }
  254.  
  255. #endif /* TWO_FILE_COMMANDLINE */
  256.  
  257.   /* Figure out the input file format, and set up to read it. */
  258.   select_file_type(&cinfo);
  259.  
  260.   /* Do it to it! */
  261.   jpeg_compress(&cinfo);
  262.  
  263.   /* Release memory. */
  264.   j_free_defaults(&cinfo);
  265. #ifdef MEM_STATS
  266.   if (e_methods.trace_level > 0)
  267.     j_mem_stats();
  268. #endif
  269.  
  270.   /* All done. */
  271.   exit(0);
  272. }
  273.